// Tests for individual cards in cardEffect()
/*
 * Test with seed 1000
 * Player 0's hand after initialization:
 * #  Card
 * 0  Copper
 * 1  Copper
 * 2  Estate
 * 3  Copper
 * 4  Copper
 */

#include "includes.h"

int player1 = 0;
int player2 = 1;
int seed = 1000;
int numPlayer = 2;
int k[10] = {adventurer, council_room, feast, gardens, mine, remodel,
		smithy, village, baron, great_hall};
struct gameState G;

/*
 * Adventurer
 * Reveal cards from your deck until you reveal 2 Treasure cards. Put those
 * Treasure cards in your hand and discard the other revealed cards.
 */
/* If no/only 1 treasure found, stop when full deck seen */
void test_adventurer1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    //Play Adventurer card with empty deck to trigger shuffle loop
    int i;
	int deckCounter;
    int card = adventurer;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    //Move cards from deck to discard, to trigger shuffle loop
    for (i = 0; i < 4; i++){
        deckCounter = G.deckCount[player1];
        G.discard[player1][i] = G.deck[player1][deckCounter - 1];
        G.deckCount[player1]--;
        G.discardCount[player1]++;
    }
    CU_ASSERT(G.deckCount[player1] == 1);		//leave 1 card in deck
    CU_ASSERT(G.discardCount[player1] == 4);
    int preHandCount = G.handCount[player1];
    int preCoins = G.coins;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount + 2 - 1); //gained 2 cards, discard adventurer card
    CU_ASSERT(G.coins == preCoins); //not the responsibility of cardEffect to sum new coin total in hand, updateCoins
}

void test_adventurer2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    //Base case, play card with a full deck.
    int card = adventurer;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int preCoins = G.coins;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount + 2 - 1); //gained 2 cards, discard adventurer card
    CU_ASSERT(G.coins == preCoins);
}

/*
 * Ambassador
 * Reveal a card from your hand. Return up to 2 copies of it from your hand to
 * the Supply. Then each other player gains a copy of it.
 */
/* choice1 = hand#, choice2 = number to return to supply */
void test_ambassador1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice1 = 3; //Reveal Copper card
    int choice2 = 2; //There are four Copper cards in hand, return 2, should pass, valid input
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 2 - 1);
}

void test_ambassador2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice1 = 3; //Reveal Copper
    int choice2 = 3; //Four Copper cards in hand, return more than 2 copies should fail, invalid input
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_ambassador3(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice1 = 3; //Reveal Copper card
    int choice2 = 0; //There are four Copper cards in hand, return 0, should pass, valid input, player could return 0 cards to the supply
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
}

void test_ambassador4(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice1 = 3; //Reveal Copper card
    int choice2 = 1; //Return 1 Copper card, should pass, valid input
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1);
}

void test_ambassador5(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice1 = 3; //Reveal Copper card
    int choice2 = -1; //Return -1 Copper card, should fail, invalid input
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_ambassador6(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice2 = 1; //valid input for chioce2(0,1,2)
    int choice3 = 0;
    //handPos(ambassador card) and choice1(reveal card) are equal, should fail
    int handPos = G.handCount[player1];
    int choice1 = handPos; //Reveal Ambassador card
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_ambassador7(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice1 = 2; //Reveal Estate card
    int choice2 = 0; //Return 0 Estate cards, should pass, valid input
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
}

void test_ambassador8(void) {//return the revealed card itself
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice1 = 2; //Reveal Estate card
    int choice2 = 1; //Return 1 Estate cards, should pass, only one Estate card in hand, valid input
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1);
}

void test_ambassador9(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = ambassador;
    int choice1 = 2; //Reveal Estate card
    int choice2 = 2; //There is only 1 Estate card in hand, should fail
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

/*
 * Baron
 * +1 Buy, You may discard an Estate card. If you do, +4 coins. Otherwise, gain
 * an Estate card.
 */
/* choice1: boolean for discard of estate */
/* Discard is always of first (lowest index) estate */
/* True, discard. False, gain. */
void test_baron1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    // True, discard Estate card and get +4 coins
    int card = baron;
    int choice1 = true;//1
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preCoins = G.coins;
    int preNumBuys = G.numBuys;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.coins == preCoins + 4);
    CU_ASSERT(G.numBuys == preNumBuys +1);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1);
}

void test_baron2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    // False, gain Estate card
    int card = baron;
    int choice1 = false;//0
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preNumBuys = G.numBuys;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.numBuys == preNumBuys +1);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount + 1);
}

void test_baron3(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    // True, no Estate card to trash, so gain Estate card
    int card = baron;
    int choice1 = true;//1
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    G.hand[player1][2] = 4; //replace Estate card in hand with Copper
    int preNumBuys = G.numBuys;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.numBuys == preNumBuys +1);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount + 1);
}

void test_baron4(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    //True, no Estate card to trash, so gain LAST Estate card, baron checks if "isGameOver"
    int card = baron;
    int choice1 = true;//1
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    G.hand[player1][2] = 4;
    G.supplyCount[estate] = 1; //last estate card
    int preNumBuys = G.numBuys;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.supplyCount[estate] == 0);
    CU_ASSERT(G.numBuys == preNumBuys +1);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount + 1);
}

void test_baron5(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    //False, no Estate card to trash, gain Estate card, LAST Estate card, baron checks if "isGameOver"
    int card = baron;
    int choice1 = false;//0
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    G.hand[player1][2] = 4;
    G.supplyCount[estate] = 1;
    int preNumBuys = G.numBuys;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.supplyCount[estate] == 0);
    CU_ASSERT(G.numBuys == preNumBuys +1);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount + 1);
}

void test_baron6(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    //False, no Estate card to trash, gain Estate card, LAST Estate card, baron checks if "isGameOver"
    int card = baron;
    int choice1 = false;//0
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    G.supplyCount[estate] = 1;
    int preNumBuys = G.numBuys;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.supplyCount[estate] == 0);
    CU_ASSERT(G.numBuys == preNumBuys +1);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount + 1);
}

/*
 * Council Room
 * +4 Cards, +1 Buy, Each other player draws a card.
 */
void test_council_room(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = council_room;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount1 = G.handCount[player1];
    int preHandCount2 = G.handCount[player2];
    int preNumBuys = G.numBuys;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    // add 4 cards to hand, discard council_room card from hand
    CU_ASSERT(G.handCount[player1] == preHandCount1 + 4 - 1);
    // add 1 buy
    CU_ASSERT(G.numBuys == preNumBuys + 1);
    // add 1 card to hand of other player
    CU_ASSERT(G.handCount[player2] == preHandCount2 + 1);
}

/*
 * Cutpurse
 * +2 Coins, Each other player discards a Copper card (or reveals a hand with
 * no Copper).
 */
void test_cutpurse1(void) { //player2 discards a copper
	int i;int deckCounter;
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = cutpurse;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    //draw player2's hand
    CU_ASSERT(G.deckCount[player2] == 10);
    for (i = 0; i < 5; i++){
        deckCounter = G.deckCount[player2];
        G.hand[player2][i] = G.deck[player2][deckCounter - 1];
        CU_ASSERT(G.hand[player2][i] != 0);
        G.deck[player2][deckCounter - 1] = 0;
        G.deckCount[player2]--;
        G.handCount[player2]++;
    }
    CU_ASSERT(G.hand[player2][0] == 4);
    CU_ASSERT(G.deckCount[player2] == 5);
    CU_ASSERT(G.handCount[player2] == 5);
    int preCoins = G.coins;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.coins == preCoins + 2);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
}

void test_cutpurse2(void) { //player2 reveals a hand with no copper
	int i;int deckCounter;
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = cutpurse;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    CU_ASSERT(G.deckCount[player2] == 10);
    for (i = 0; i < 5; i++){
        deckCounter = G.deckCount[player2];
        G.hand[player2][i] = 1; //Estate Card
        CU_ASSERT(G.hand[player2][i] != 0);
        G.deck[player2][deckCounter - 1] = 0;
        G.deckCount[player2]--;
        G.handCount[player2]++;
    }
    CU_ASSERT(G.deckCount[player2] == 5);
    CU_ASSERT(G.handCount[player2] == 5);
    int preCoins = G.coins;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.coins == preCoins + 2);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
}

/*
 * Embargo
 * +2 Coins, Trash this card. Put an Embargo token on top of a Supply pile. /
 * When a player buys a card, he gains a Curse card per Embargo token on that
 * pile.
 */
/* choice1 = supply# */
void test_embargo1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = embargo;
    int choice1 = province; //3
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preCoins = G.coins;
    int preHandCount = G.handCount[player1];
    int prePlayedCardCount = G.playedCardCount;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.coins == preCoins + 2);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1);
    CU_ASSERT(G.playedCardCount == prePlayedCardCount + 1);
}

void test_embargo2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = embargo;
    int choice1 = outpost; //pile not in play, Outpost card, 23
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preCoins = G.coins;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
    CU_ASSERT(G.coins == preCoins);
}

/*
 * Feast
 * Trash this card. Gain a card costing up to 5 Coins.
 */
/* choice1 is supply # of card gained) */
void test_feast1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = feast;
    int choice1 = 5; //Silver, cost is 3, affordable, less than 5
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount + 1 - 1);
}

void test_feast2(void) { //None of that card left
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = feast;
    int choice1 = village; //Village, cost is 3, affordable, less than 5
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    G.supplyCount[village] = 0; //No more of this card left
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_feast3(void) {//Card is too expensive
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = feast;
    int choice1 = 3; //Province, cost is 8, not affordable, more than 5
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_feast4(void) { //Card is too expensive
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = feast;
    int choice1 = 7; //Adventurer, cost is 6, not affordable, more than 5
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_feast5(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = feast;
    int choice1 = 11; //Mine, cost is 5, affordable, equal to 5
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount + 1 - 1);
}

/*
 * Gardens
 * Worth 1 VP for every 10 cards in your deck (rounded down).
 */
void test_gardens(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = gardens;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

/*
 * Great Hall
 * +1 Card, +1 Action, 1 VP
 */
void test_great_hall(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = great_hall;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preNumActions = G.numActions;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.numActions == preNumActions + 1);
    CU_ASSERT(G.handCount[player1] == preHandCount + 1 - 1);
}

/*
 * Mine
 * Trash a Treasure card from your hand. Gain a Treasure card costing up to 3
 * Coins more; put it into your hand.
 */
/* choice1 is hand# of money to trash, choice2 is supply# of money to put in hand */


void test_mine1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Copper, valid
    int choice2 = 5;//Silver card, valid input, should pass
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1 + 1);
}

void test_mine2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Silver, valid
    G.hand[player1][choice1] = silver;
    int choice2 = 6;//Gold card, valid input, should pass
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1 + 1);
}

void test_mine3(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Gold, valid
    G.hand[player1][choice1] = gold;
    int choice2 = 6;//Gold card, valid input, should pass
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1 + 1);
}

void test_mine4(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Gold, valid
    G.hand[player1][choice1] = gold;
    int choice2 = 5;//Silver card, valid input, should pass
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1 + 1);
}

void test_mine5(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Gold, valid
    G.hand[player1][choice1] = gold;
    int choice2 = 4;//Copper card, valid input, should pass
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1 + 1);
}

void test_mine6(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Silver, valid
    G.hand[player1][choice1] = silver;
    int choice2 = 5;//Silver card, valid input, should pass
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1 + 1);
}

void test_mine7(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Silver, valid
    G.hand[player1][choice1] = silver;
    int choice2 = 4;//Copper card, valid input, should pass
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1 + 1);
}

void test_mine8(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Copper, valid
    int choice2 = 4;//Copper card, valid input, should pass
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1 + 1);
}

void test_mine9(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Copper, valid
    int choice2 = 6;//Gold card, not valid input, should fail
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
    CU_ASSERT(G.handCount[player1] == preHandCount);
}

void test_mine10(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Copper
    int choice2 = treasure_map; //not a treasure card, should fail
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
    CU_ASSERT(G.handCount[player1] == preHandCount);
}

void test_mine11(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 0;//Copper
    int choice2 = treasure_map+1;//not a valid card, invalid input
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_mine12(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 2;//Estate, not a treasure card invalid
    int choice2 = treasure_map;//not a valid card, invalid input, should fail
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_mine13(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = -1;//garbage input, invalid
    int choice2 = treasure_map;//not a valid card, invalid input, should fail
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_mine14(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = mine;
    int choice1 = 2; //Estate, not a treasure card, invalid input, should fail
    int choice2 = 0; //Curse card, invalid input, should fail
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

/*
 * Minion
 * +1 Action, Choose one: +2 Coins; or discard your hand, +4 Cards, and each
 * other player with at least 5 cards in hand discards his hand and draws 4 cards.
 */
/* choice1:  1 = +2 coin, 2 = redraw */
void test_minion1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = minion;
    int choice1 = 1;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preCoins = G.coins;
    int preNumActions = G.numActions;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.coins == preCoins + 2);
    CU_ASSERT(G.numActions == preNumActions + 1);
}

void test_minion2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = minion;
    int choice1 = 0;
    int choice2 = 1;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preNumActions = G.numActions;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.numActions == preNumActions + 1);
    CU_ASSERT(G.handCount[player1] == 4);
}

void test_minion3(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int count; int deckCounter;int i;
    int card = minion;
    int choice1 = 0;
    int choice2 = 1;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    count = G.deckCount[player2];
    for (i = count-1; i > count-6; i--){
        deckCounter = G.deckCount[player2];
        G.hand[player2][i] = G.deck[player2][deckCounter - 1];
        G.deck[player2][deckCounter - 1] = 0;
        G.deckCount[player2]--;
        G.handCount[player2]++;
    }
    CU_ASSERT(G.deckCount[player2] == 5);
    CU_ASSERT(G.handCount[player2] == 5);
    int preNumActions = G.numActions;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.numActions == preNumActions + 1);
    CU_ASSERT(G.handCount[player1] == 4);
    CU_ASSERT(G.handCount[player2] == 4);
}

/*
 * Outpost
 * You only draw 3 cards (instead of 5) in this turn's Clean-up phase. Take an
 * extra turn after this one. This can't cause you to take more than two
 * consecutive turns.
 */
void test_outpost(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = outpost;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
}

/*
 * Remodel
 * Trash a card from your hand. Gain a card costing up to 2 Coins more than the
 * trashed card.
 */
/* choice1 is hand# of card to remodel, choice2 is supply# */
void test_remodel1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = remodel;
    int choice1 = 2;  //hand index 2, Estate, cost 2
    int choice2 = 14; //supply index 14, Village, cost 3, affordable
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount + 1);
}

void test_remodel2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = remodel;
    int choice1 = 2; //hand index 2, Estate, cost 2
    int choice2 = 7; //supply index 7, Adventurer, cost 4, not affordable
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
}

void test_remodel3(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = remodel;
    int choice1 = 2; //hand index 2, Estate, cost 2
    int choice2 = 13; //supply index 13, Smithy, cost 4, affordable
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount + 1);
}

void test_remodel4(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = remodel;
    int choice1 = 2; //hand index 2, Estate, cost 2
    int choice2 = 5; //supply index 5, Silver, not from the Supply, invalid
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
    CU_ASSERT(G.handCount[player1] == preHandCount);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount);
}

void test_remodel5(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = remodel;
    int choice1 = 2; //hand index 2, Estate, cost 2
    int choice2 = treasure_map + 1; //not a valid card, invalid
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int preDiscardCount = G.discardCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == -1);
    CU_ASSERT(G.handCount[player1] == preHandCount);
    CU_ASSERT(G.discardCount[player1] == preDiscardCount);
}

/*
 * Salvager
 * +1 Buy, Trash a card from your hand. +Coin equal to its cost.
 */
/* choice1 = hand# to trash */
void test_salvager(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);

    int card = salvager;
    int choice1 = 1;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preNumBuys = G.numBuys;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.numBuys == preNumBuys +1);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1);
}

/*
 * Sea Hag
 * Each other player discards the top card of his deck, then gains a Curse card,
 * putting it on top of his deck.
 */
void test_sea_hag(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = sea_hag;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int prePlayedCardCount = G.playedCardCount;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.playedCardCount == prePlayedCardCount + 1);
}

/*
 * Smithy
 * +3 Cards.
 */
void test_smithy(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = smithy;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    // smithy adds 3 cards; check state->handCount
    //add 3 cards to hand, discard smith card from hand
    CU_ASSERT(G.handCount[player1] == preHandCount + 3 - 1);
}

/*
 * Steward
 * Choose one: +2 Cards; or +2 Coins; or trash 2 cards from your hand.
 */
/* choice1: 1 = +2 card, 2 = +2 coin, 3 = trash 2 (choice2,3) */
void test_steward1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = steward;
    int choice1 = 1;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount+2-1);
}

void test_steward2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = steward;
    int choice1 = 2;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preCoins = G.coins;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.coins == preCoins + 2);
}

void test_steward3(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = steward;
    int choice1 = 0;
    int choice2 = 1;
    int choice3 = 2;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 2 - 1);
}

/*
 * Treasure Map
 * Trash this and another copy of Treasure Map from your hand. If you do trash
 * two Treasure Maps, gain 4 Gold cards, putting them on top of your deck.
 */
void test_treasure_map1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = treasure_map;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    //no treasure map card in hand, need two to play, fails.
    CU_ASSERT(check == -1);
}

void test_treasure_map2(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = treasure_map;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int handTop = G.handCount[player1];
    //add treasure map card to player's hand
    G.hand[player1][handTop] = card;
    G.handCount[player1]++;
    int preHandCount = G.handCount[player1];
    int prePlayedCardCount = G.playedCardCount;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.handCount[player1] == preHandCount - 1 - 1);
    CU_ASSERT(G.playedCardCount == prePlayedCardCount + 2);
}

/*
 * Tribute
 * The player to your left reveals then discards the top 2 cards of his deck.
 * For each differently named card revealed, if it is an Action card, +2
 * Actions; Treasure Card +2 Coins; Victory Card, +2 Cards.
 */
void test_tribute1(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = tribute;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int prePlayedCardCount = G.playedCardCount;
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    CU_ASSERT(G.playedCardCount == prePlayedCardCount + 1);
}

void test_tribute2(void) {
	int i;int count;int deckCounter;int j;
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = tribute;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    //Move all cards from deck to hand
    for (i = 0; i < 10; i++){
        deckCounter = G.deckCount[player2];
        G.hand[player2][i] = G.deck[player2][deckCounter - 1];
        G.deckCount[player2]--;
        G.handCount[player2]++;
    }
    CU_ASSERT(G.deckCount[player2] == 0);
    //Add 2 cards to discard pile
    count = G.handCount[player2];j=0;
    for(i = count;i>count-2;i--) {
    	G.discard[player2][j] = G.hand[player2][i];
    	G.hand[player2][i] = 0;
    	G.handCount[player2]--;
    	G.discardCount[player2]++;
    	j++;
    }
    CU_ASSERT(G.discardCount[player2] == 2);
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
}

void test_tribute3(void) {
	int i;int deckCounter;
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = tribute;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    //Move 9 cards from deck to hand
    for (i = 0; i < 9; i++){
        deckCounter = G.deckCount[player2];
        G.hand[player2][i] = G.deck[player2][deckCounter - 1];
        G.deckCount[player2]--;
        G.handCount[player2]++;
    }
    CU_ASSERT(G.deckCount[player2] == 1);
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
}

void test_tribute4(void) {
	int i;int count;int deckCounter;int j;
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = tribute;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    //Move all cards from deck to hand
    for (i = 0; i < 10; i++){
        deckCounter = G.deckCount[player2];
        G.hand[player2][i] = G.deck[player2][deckCounter - 1];
        G.deckCount[player2]--;
        G.handCount[player2]++;
    }
    CU_ASSERT(G.deckCount[player2] == 0);
    //Move 1 card from hand to discard pile
    count = G.handCount[player2];j=0;
    for(i = count;i>count-1;i--) {
    	G.discard[player2][j] = G.hand[player2][i];
    	G.hand[player2][i] = 0;
    	G.handCount[player2]--;
    	G.discardCount[player2]++;
    	j++;
    }
    CU_ASSERT(G.discardCount[player2] == 1);
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
}

void test_tribute5(void) {
	int i;int deckCounter;
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = tribute;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    //Move all cards from deck to hand
    for (i = 0; i < 10; i++){
        deckCounter = G.deckCount[player2];
        G.hand[player2][i] = G.deck[player2][deckCounter - 1];
        G.deckCount[player2]--;
        G.handCount[player2]++;
    }
    CU_ASSERT(G.deckCount[player2] == 0);
    CU_ASSERT(G.discardCount[player2] == 0);
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
}

/*
 * Village
 * +1 Card, +2 Actions
 */
void test_village(void) {
    memset(&G, 0, sizeof(struct gameState));
    initializeGame(numPlayer, k, seed, &G);
    int card = village;
    int choice1 = 0;
    int choice2 = 0;
    int choice3 = 0;
    int handPos = G.handCount[player1];
    G.hand[player1][handPos] = card;
    G.handCount[player1]++;
    int bonus = 0;
    int preNumActions = G.numActions;
    int preHandCount = G.handCount[player1];
    int check = cardEffect(card, choice1, choice2, choice3, &G, handPos, &bonus);
    CU_ASSERT(check == 0);
    // villages adds 2 actions and 1 card
    CU_ASSERT(G.numActions == preNumActions + 2);
    //add card to hand, discard village card from hand
    CU_ASSERT(G.handCount[player1] == preHandCount + 1 - 1);
}
